#!/usr/bin env python3
# filename: doto.py

from datetime import datetime
import hashlib
from flask import Flask, render_template, url_for, request, redirect,\
    flash, g

from flask_bootstrap import Bootstrap
from flask_login import login_user, logout_user, login_required, current_user

# 坑点：千万别把包名写上,,,,,,,,,,,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
from forms import ToDoListForm, LoginForm, CheckMailForm, RegisterForm
from todo_list_models import TodoList, User
from ext import db, login_manager
from check_mail import check_mails
from gen_code import gen_random_code


app = Flask(__name__)
bootstrap = Bootstrap(app)

SECRET_KEY = "KEY_FOR_SECRET"
app.secret_key = SECRET_KEY
app.config['USERNAME'] = "hzsai"
app.config['PASSWORD'] = "hzsszh"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
config = "mysql+pymysql://hzsai:hzsszh@127.0.0.1:3306/tododatabase"
app.config['SQLALCHEMY_DATABASE_URI'] = config

db.init_app(app)
login_manager.init_app(app)
login_manager.login_view = "login"

# Note:
# url_for似乎只是导到route已经存在的路径, 在html文件中，使用相对路径是可以的(相对当前的路径)!!!
# 模板的block 是替换的关系，，替换，替换，替换


@app.route('/')
@login_required
def main():
    return redirect(url_for('show_to_do_list', page=1))


@app.route('/show_to_do_list/<int:page>', methods=['GET', 'POST'])
@login_required
def show_to_do_list(page=1):
    form = ToDoListForm()
    if request.method == 'GET':
        todo_list_pages = TodoList.query.order_by(db.desc(TodoList.create_time)).paginate(page, 50, error_out=False)
        todo_list = todo_list_pages
        # ATTENTION: >>>>>>>>> BUG BELOW <<<<<<<<<
        return render_template('index.html', todo_list=todo_list, form=form)
    elif request.method == 'POST':
        # id user_id, title, status, create_time
        if form.validate_on_submit():
            todolist = TodoList(1, form.title.data, form.status.data)
            db.session.add(todolist)
            db.session.commit()
            flash("插入成功.")
        else:
            flash(form.errors)
        return redirect(url_for('show_to_do_list', page=page))
    else:
        pass


# TODO:
@app.route('/login', methods=['GET', 'POST'])
def login():

    # NEED TO UPDATE ....
    form = LoginForm()
    if request.method == 'POST':
        # if the username, password exists,
        paudo_password = hashlib.md5(form.password.data.encode('utf8')).hexdigest()
        user = User.query.filter_by(username=form.username.data, password=paudo_password).first()
        g.user = user
        print(user)
        if user:
            login_user(user)
            flash("欢迎，{0}，\(^o^)/~".format(user.username))
            return redirect(url_for('show_to_do_list', page=1))
        else:
            flash("用户名或密码错误")
    return render_template('login.html', form=form)


@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash("你登出了!")
    return redirect(url_for('login'))


@app.route('/register', methods=['GET', 'POST'])
def register():
    valid_code = gen_random_code(5)
    if request.method == 'GET':
        return render_template('register.html', valid_code=valid_code)
    elif request.method == 'POST':
        # username, password, validecode

        # BUG   <<<<<<<< BUG HERE >>>>>>
        username = request.form['username']
        password = request.form['password']
        valid_ori = request.form['valid_ori']
        valid_inp = request.form['valid_inp']

        # debug
        print(username)
        print(password)
        print(valid_inp)
        print(valid_ori)

        if valid_inp != valid_ori:
            flash("验证码错误")
            return redirect(url_for('register'))
        else:
            ret = User.query.filter_by(username=username).first()
            print(ret)
            if ret is None:
                # insert into the database
                passwd_hash = hashlib.md5(password.encode('utf8')).hexdigest()
                new_user = User(username, passwd_hash)
                print(passwd_hash)
                print(new_user)
                try:
                    print("Oldldld")
                    # TODO: BUG HERE <<<<< BUG !!! db.session.add failed .>>>>>
                    # Fixed
                    # LOOKUP: the SQLAlachemy doc.
                    db.session.add(new_user)
                    db.session.commit()
                    print("W......")
                    login_user(new_user)
                    print("A......")
                    flash("欢迎，{0}，[]~(￣▽￣)~*".format(new_user.username))
                    return redirect(url_for('show_to_do_list', page=1))
                except:
                    flash("好像出现了什么问题( •̀ ω •́ )y")
                    db.session.rollback()
                    return redirect(url_for('register'))
            else:
                flash("用户名已经存在了(⊙o⊙)！...")
                return redirect(url_for('register'))
    else:
        print("NSLJDSFLSKJF:LSD")


@app.route('/modify/<int:id>', methods=['GET', 'POST'])
@login_required
def modify_to_do(id):
    todo = TodoList.query.filter_by(id=id).first_or_404()
    form = ToDoListForm()
    if request.method == 'GET':
        form.title.data = todo.title
        form.status.data = str(todo.status)
        return render_template('modify.html', form=form)
    elif request.method == 'POST':
        if form.validate_on_submit():
            todo.title = form.title.data
            todo.status = form.status.data
            new_todo = todo
            new_todo.title = form.title.data
            new_todo.status = form.status.data
            db.session.delete(todo)
            db.session.add(new_todo)
            db.session.commit()
            flash("成功更改.")
        else:
            pass
        return redirect(url_for('show_to_do_list', page=1))
    else:
        pass


@app.route('/delete/<int:id>')
@login_required
def delete_to_do(id):
    print(id)
    todolist = TodoList.query.filter_by(id=id).first_or_404()
    print(todolist)
    db.session.delete(todolist)
    db.session.commit()
    flash("成功删除")
    return redirect(url_for('show_to_do_list', page=1))


@app.route('/check_mail', methods=['GET', 'POST'])
@login_required
def check_mail():
    mailForm = CheckMailForm()
    message = None
    if request.method == 'GET':
        return render_template('check_mail.html', messages=None, form=mailForm)
    elif request.method == 'POST':
        if mailForm.validate_on_submit():
            mail_id = mailForm.mail_id.data
            if mail_id is None:
                flash("Mail id Wrong!!!")
                return redirect(url_for('check_mail'))
            else:
                mail_id = int(mail_id)
                message = check_mails(mail_id)
        else:
            flash(mailForm.errors)
        return render_template('check_mail.html', messages=message, form=mailForm)
    else:
        pass


@login_manager.user_loader
def load_user(user_id):
    return User.query.filter_by(id=user_id).first()


if __name__ == '__main__':

    app.run(host="127.0.0.1", port=5004, debug=True)
